<!doctype html>
<html>
<head>
    <link rel="stylesheet" href="styles/example.css">

    <script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>

    <link rel="stylesheet" href="./styles/github.css">
    <script src="js/highlight.pack"></script>

    <link rel="stylesheet" href="styles/tabpage.css">
    <script type="text/cbs" src="cbs/tabpage.pkg.cbs"></script>
    <script type="text/cbs" src="cbs/sourceTab.pkg.cbs"></script>

    <script src="../src/core/PrivateScope.js"></script>
    <script src="../src/core/Utility.js"></script>
    <script src="../src/core/Deferred.js"></script>
    <script src="../src/core/AttachedData.js"></script>
    <script src="../src/core/DataObserver.js"></script>
    <script src="../src/core/ArrayMonitor.js"></script>
    <script src="../src/core/GlobalSymbolHelper.js"></script>
    <script src="../src/core/OptionParser.js"></script>
    <script src="../src/core/KnotManager.js"></script>
    <script src="../src/core/CBSLoader.js"></script>
    <script src="../src/core/HTMLAPProvider.js"></script>
    <script src="../src/core/HTMLKnotBuilder.js"></script>
    <script src="../src/core/AddonHTMLAPProvider.js"></script>
    <script src="../src/core/ComponentAPProvider.js"></script>
    <script src="../src/core/KnotInterface.js"></script>

    <link rel="stylesheet" href="styles/tabpage.css" id="tabpageCSS">
    <script type="text/cbs" src="cbs/tabpage.pkg.cbs" id="tabpageCBS"></script>
    <script type="text/cbs" src="cbs/sourceTab.pkg.cbs"></script>
    <script src="js/tabpage.js" id="tabPageSource"></script>
    <script type="text/javascript" src="js/sourceTab.js"></script>

    <script src="../src/debugger/knot.debug.js"></script>

    <style type="text/css" class="exampleCSS">
    .section{
        margin: 5px;
    }
    .errMessage{
        color:red;
    }
    .errorInput {
        box-shadow: 0px 0px 5px red;
    }
    </style>

    <script type="text/cbs"  class="exampleCBS">

    /*
    this bind the style of the input to the error status of it's value for all of the
    inputs in the form by this knot, the input will get red glow when it's value is invalid
     */
    form input[type=text]{
        class: !*LEFT.value>@{return value?"+errorInput":"-errorInput";}
    }


    #nameSection{
        /*
        add empty check and length check to the "name" text box
        bind to *NULL so that we don't need to create a data model for it.
        */
        -> input{
            value> @/validator.notEmpty> {
                    /* you can use either  */
                    if(value.length < 3)
                        throw new Error("Name must be more than 3 characters");
                    if(value.length > 10)
                        throw new Error("Name must be no more than 10 characters");
                    return value;
                }: *NULL;
        };

        /* bind the text to the "message" of error status of the value of the "name" input box.  */
        -> .errMessage{
            text:!#(#nameSection input).value>{return value?value.message:"";}
        };
    }

    #ageSection{
        /*add empty check, number format check and number range check to the "age" text box*/
        ->input{
            value> @/validator.notEmpty> @/validator.checkAndConvertToNumber> @/validator.checkAgeRange : *NULL;
        };

        -> .errMessage{
            text:!#(#ageSection input).value>{return value?value.message:"";}
        }
     }

    #emailSection{
        /*add empty check, email format check to the "email" text box*/
         ->input{
            value>@/validator.notEmpty> {
                if(!/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(value))
                    throw new Error("Invalid email!");
                return value;
            }:*NULL;
        };

        ->.errMessage{
            text:!#(#emailSection input).value>{return value?value.message:"";}
        }
    }
    </script>
    <script class="exampleJS">
        //these functions will be called by knot.js system.
        window.validator ={
            notEmpty: function (v) {
                if(v.trim() == "")
                    throw new Error("Can't be null.")
                return v;
            },
            checkAndConvertToNumber: function (v) {
                v = parseInt(v);
                if(isNaN(v))
                    throw new Error("Age must be a number!");
                return v;
            },
            checkAgeRange: function (v) {
                if(v<0 || v>150) {
                    throw new Error("Age must be in the range of 0~150")
                }
                return v;
            }
        };

        //validate the whole page, show the error messages if there's error
        function validate() {
            var err = Knot.getErrorStatusInformation();
            if(err.length > 0) {
                var msg = "Error detected:";
                for(var i=0; i< err.length; i++) {
                    msg += "\n - " + err[i].node.placeholder  + ": " + err[i].error.message;
                }
                alert(msg);
                //set the focus to the first element in error status
                err[0].node.focus();
                return false;
            }
            alert("Let's fake it is committed !");
            return true;
        }
    </script>
</head>
<body>
<div class="knot_example">
    <h2>Knot.js example - input validate</h2>
    <form action="" onsubmit="return validate();">
        <div class="section" id="nameSection">
            <input type="text" placeholder="Name">  <span class="errMessage"></span>
        </div>
        <div class="section" id="ageSection">
            <input type="text" placeholder="Age">  <span class="errMessage"></span>
        </div>
        <div class="section" id="emailSection">
            <input type="text" placeholder="Email">  <span class="errMessage"></span>
        </div>

        <input type="submit">
    </form>
</div>


<div id="sourceTab" knot-debugger-ignore  knot-component="SourceTabPage">
</div>
<script type="text/cbs">
        #sourceTab{
            sourceInfo:/sourceCodeInfo.codes
        }
    </script>
<script>
    //collect source codes before knot changes the HTML
    window.sourceCodeInfo = {codes:null};

    window.SourceCodeHelper.collectSourceCodes(
            [{selector:".knot_example",title:"HTML", type:"html"},
                {selector:".exampleJS",title:"Javascript", type:"javascript"},
                {selector:".exampleCBS",title:"CBS", type:"cbs"},
                {selector:".exampleCSS",title:"CSS", type:"css"}],
            function(res){
                window.sourceCodeInfo.codes = res;
            });
</script>
</body>
</html>